<script lang="ts" setup>
import { useToast } from 'vue-toast-notification'
import MediaIdSelector from '../misc/MediaIdSelector.vue'
import store from '@/store'
import api from '@/api'
import { numberValidator } from '@/@validators'
import { useDisplay } from 'vuetify'
import ProgressDialog from './ProgressDialog.vue'
import { FileItem, MediaDirectory } from '@/api/types'

// 显示器宽度
const display = useDisplay()

// 输入参数
const props = defineProps({
  storage: {
    type: String,
    default: () => 'local',
  },
  logids: Array<number>,
  items: Array<FileItem>,
  target: String,
})

// 定义事件
const emit = defineEmits(['done', 'close'])

// 生成1到100季的下拉框选项
const seasonItems = ref(
  Array.from({ length: 101 }, (_, i) => i).map(item => ({
    title: `第 ${item} 季`,
    value: item,
  })),
)

// 当前识别类型
const mediaSource = ref('themoviedb')

// 提示框
const $toast = useToast()

// TMDB选择对话框
const mediaSelectorDialog = ref(false)

// 加载进度SSE
const progressEventSource = ref<EventSource>()

// 整理进度条
const progressDialog = ref(false)

// 整理进度文本
const progressText = ref('请稍候 ...')

// 整理进度
const progressValue = ref(0)

// 标题
const dialogTitle = computed(() => {
  if (props.items) {
    if (props.items.length > 1) return `整理 - 共 ${props.items.length} 项`
    return `整理 - ${props.items[0].path}`
  } else if (props.logids) {
    return `整理 - 共 ${props.logids.length} 项`
  }
  return '手动整理'
})

// 表单
const transferForm = reactive({
  storage: props.storage,
  logid: 0,
  path: '',
  drive_id: '',
  fileid: '',
  filetype: '',
  target: props.target ?? null,
  tmdbid: null,
  doubanid: null,
  season: null,
  type_name: '',
  transfer_type: '',
  episode_format: '',
  episode_detail: '',
  episode_part: '',
  episode_offset: null,
  min_filesize: 0,
  scrape: false,
})

// 所有媒体库目录
const libraryDirectories = ref<MediaDirectory[]>([])

// 目的目录下拉框
const targetDirectories = computed(() => {
  const directories = libraryDirectories.value.map(item => item.path)
  return [...new Set(directories)]
})

// 监听目的路径变化，自动查询目录的刮削配置
watch(transferForm, async () => {
  if (transferForm.target) {
    const directory = libraryDirectories.value.find(item => item.path === transferForm.target)
    if (directory) {
      transferForm.scrape = directory.scrape ?? false
    }
  }
})

// 使用SSE监听加载进度
function startLoadingProgress() {
  progressText.value = '请稍候 ...'

  const token = store.state.auth.token

  progressEventSource.value = new EventSource(
    `${import.meta.env.VITE_API_BASE_URL}system/progress/filetransfer?token=${token}`,
  )
  progressEventSource.value.onmessage = event => {
    const progress = JSON.parse(event.data)
    if (progress) {
      progressText.value = progress.text
      progressValue.value = progress.value
    }
  }
}

// 停止监听加载进度
function stopLoadingProgress() {
  progressEventSource.value?.close()
}

// 整理文件
async function transfer() {
  if (!props.logids && !props.items) return

  // 显示进度条
  progressDialog.value = true
  // 开始监听进度
  startLoadingProgress()

  // 文件整理
  if (props.items) {
    for (const item of props.items) {
      await handleTransfer(item)
    }
  }

  // 日志整理
  if (props.logids) {
    for (const logid of props.logids) {
      await handleTransferLog(logid)
    }
  }

  // 停止监听进度
  stopLoadingProgress()
  // 关闭进度条
  progressDialog.value = false
  // 重新加载
  emit('done')
}

// 整理文件
async function handleTransfer(item: FileItem) {
  transferForm.path = item.path
  transferForm.fileid = item.fileid || ''
  transferForm.drive_id = item.drive_id || ''
  transferForm.filetype = item.type || 'dir'

  try {
    const result: { [key: string]: any } = await api.post('transfer/manual', {}, { params: transferForm })
    if (!result.success) $toast.error(`文件 ${item.path} 整理失败：${result.message}！`)
  } catch (e) {
    console.log(e)
  }
}

// 整理日志
async function handleTransferLog(logid: number) {
  transferForm.logid = logid
  try {
    const result: { [key: string]: any } = await api.post('transfer/manual', {}, { params: transferForm })
    if (!result.success) $toast.error(`历史记录 ${logid} 重新整理失败：${result.message}！`)
  } catch (e) {
    console.log(e)
  }
}

// 调用API，加载当前系统环境设置
async function loadSystemSettings() {
  try {
    const result: { [key: string]: any } = await api.get('system/env')
    if (result) mediaSource.value = result.data?.RECOGNIZE_SOURCE || 'themoviedb'
  } catch (e) {
    console.error(e)
  }
}

// 查询媒体库目录
async function loadLibraryDirectories() {
  try {
    const result: { [key: string]: any } = await api.get('system/setting/LibraryDirectories')
    if (result.success && result.data?.value) {
      libraryDirectories.value = result.data.value
    }
  } catch (error) {
    console.log(error)
  }
}

onMounted(() => {
  loadSystemSettings()
  loadLibraryDirectories()
})
</script>

<template>
  <VDialog scrollable max-width="50rem" :fullscreen="!display.mdAndUp.value">
    <VCard :title="dialogTitle" class="rounded-t">
      <DialogCloseBtn @click="emit('close')" />
      <VDivider />
      <VCardText>
        <VForm @submit.prevent="() => {}">
          <VRow>
            <VCol v-if="props.storage == 'local'" cols="12" md="8">
              <VCombobox
                v-model="transferForm.target"
                :items="targetDirectories"
                label="目的路径"
                placeholder="留空自动"
                hint="整理目的路径，留空将自动匹配"
                persistent-hint
              />
            </VCol>
            <VCol v-if="props.storage == 'local'" cols="12" md="4">
              <VSelect
                v-model="transferForm.transfer_type"
                label="整理方式"
                :items="[
                  { title: '默认', value: '' },
                  { title: '移动', value: 'move' },
                  { title: '复制', value: 'copy' },
                  { title: '硬链接', value: 'link' },
                  { title: '软链接', value: 'softlink' },
                  { title: 'Rclone复制', value: 'rclone_copy' },
                  { title: 'Rclone移动', value: 'rclone_move' },
                ]"
                hint="文件操作整理方式"
                persistent-hint
              />
            </VCol>
          </VRow>
          <VRow>
            <VCol cols="12" md="4">
              <VSelect
                v-model="transferForm.type_name"
                label="类型"
                :items="[
                  { title: '自动', value: '' },
                  { title: '电影', value: '电影' },
                  { title: '电视剧', value: '电视剧' },
                ]"
                hint="文件的媒体类型"
                persistent-hint
              />
            </VCol>
            <VCol cols="12" md="4">
              <VTextField
                v-if="mediaSource === 'themoviedb'"
                v-model="transferForm.tmdbid"
                :disabled="transferForm.type_name === ''"
                label="TheMovieDb编号"
                placeholder="留空自动识别"
                :rules="[numberValidator]"
                append-inner-icon="mdi-magnify"
                hint="按名称查询媒体编号，留空自动识别"
                persistent-hint
                @click:append-inner="mediaSelectorDialog = true"
              />
              <VTextField
                v-else
                v-model="transferForm.doubanid"
                :disabled="transferForm.type_name === ''"
                label="豆瓣编号"
                placeholder="留空自动识别"
                :rules="[numberValidator]"
                append-inner-icon="mdi-magnify"
                hint="按名称查询媒体编号，留空自动识别"
                persistent-hint
                @click:append-inner="mediaSelectorDialog = true"
              />
            </VCol>
            <VCol cols="12" md="4">
              <VSelect
                v-show="transferForm.type_name === '电视剧'"
                v-model.number="transferForm.season"
                label="季"
                :items="seasonItems"
                hint="指定季数"
                persistent-hint
              />
            </VCol>
          </VRow>
          <VRow>
            <VCol cols="12" md="8">
              <VTextField
                v-model="transferForm.episode_format"
                label="集数定位"
                placeholder="使用{ep}定位集数"
                hint="使用{ep}定位文件名中的集数部分以辅助识别"
                persistent-hint
              />
            </VCol>
            <VCol cols="12" md="4">
              <VTextField
                v-model="transferForm.episode_detail"
                label="指定集数"
                placeholder="起始集,终止集，如1或1,2"
                hint="指定集数或范围，如1或1,2"
                persistent-hint
              />
            </VCol>
            <VCol cols="12" md="4">
              <VTextField
                v-model="transferForm.episode_part"
                label="指定Part"
                placeholder="如part1"
                hint="指定Part，如part1"
                persistent-hint
              />
            </VCol>
            <VCol cols="12" md="4">
              <VTextField
                v-model.number="transferForm.episode_offset"
                label="集数偏移"
                placeholder="如-10"
                hint="集数偏移运算，如-10或EP*2"
                persistent-hint
              />
            </VCol>
            <VCol cols="12" md="4">
              <VTextField
                v-model.number="transferForm.min_filesize"
                label="最小文件大小（MB）"
                :rules="[numberValidator]"
                placeholder="0"
                hint="只整理大于最小文件大小的文件"
                persistent-hint
              />
            </VCol>
          </VRow>
          <VRow>
            <VCol cols="12" md="6">
              <VSwitch
                v-model="transferForm.scrape"
                label="刮削元数据"
                hint="整理完成后自动刮削元数据"
                persistent-hint
              />
            </VCol>
          </VRow>
        </VForm>
      </VCardText>
      <VCardActions class="pt-3">
        <VSpacer />
        <VBtn variant="elevated" @click="transfer" prepend-icon="mdi-arrow-right-bold" class="px-5"> 开始整理 </VBtn>
      </VCardActions>
    </VCard>
    <!-- 手动整理进度框 -->
    <ProgressDialog v-if="progressDialog" v-model="progressDialog" :text="progressText" :value="progressValue" />
    <!-- TMDB ID搜索框 -->
    <VDialog v-model="mediaSelectorDialog" width="40rem" scrollable max-height="85vh">
      <MediaIdSelector
        v-if="mediaSource === 'themoviedb'"
        v-model="transferForm.tmdbid"
        @close="mediaSelectorDialog = false"
        :type="mediaSource"
      />
      <MediaIdSelector
        v-else
        v-model="transferForm.doubanid"
        @close="mediaSelectorDialog = false"
        :type="mediaSource"
      />
    </VDialog>
  </VDialog>
</template>
